using System;
using System.Collections.Generic;
using SimpleJSON;

namespace Gj
{
    internal class Event
    {
        public Action On;
        public Action<JSONArray> OnArr;
        public Action<bool> OnBool;
        public Action<float> OnFloat;
        public Action<int> OnInt;
        public Action<JSONObject> OnObj;
        public Action<string> OnStr;
    }

    public class EasyEvent
    {
        private readonly Dictionary<string, Event> eventMap = new();

        private Event GetEvent(string key)
        {
            return eventMap[key];
        }

        protected void Emit(string key)
        {
            var e = GetEvent(key);
            if (e == null) return;
            if (e.On != null) e.On();
        }

        protected void Emit(string key, string s)
        {
            var e = GetEvent(key);
            if (e == null) return;
            if (e.OnStr != null) e.OnStr(s);
        }

        protected void Emit(string key, bool b)
        {
            var e = GetEvent(key);
            if (e == null) return;
            if (e.OnBool != null) e.OnBool(b);
        }

        protected void Emit(string key, float f)
        {
            var e = GetEvent(key);
            if (e == null) return;
            if (e.OnFloat != null) e.OnFloat(f);
        }

        protected void Emit(string key, int i)
        {
            var e = GetEvent(key);
            if (e == null) return;
            if (e.OnInt != null) e.OnInt(i);
        }

        protected void Emit(string key, JSONObject obj)
        {
            var e = GetEvent(key);
            if (e == null) return;
            if (e.OnObj != null) e.OnObj(obj);
        }

        protected void Emit(string key, JSONArray arr)
        {
            var e = GetEvent(key);
            if (e == null) return;
            if (e.OnArr != null) e.OnArr(arr);
        }

        private void On(string key, Event e)
        {
            eventMap[key] = e;
        }

        public void On(string key, Action action)
        {
            var e = GetEvent(key);
            if (e == null) e = new Event();
            e.On = action;
            On(key, e);
        }

        public void On(string key, Action<string> action)
        {
            var e = GetEvent(key);
            if (e == null) e = new Event();
            e.OnStr = action;
            On(key, e);
        }

        public void On(string key, Action<bool> action)
        {
            var e = GetEvent(key);
            if (e == null) e = new Event();
            e.OnBool = action;
            On(key, e);
        }

        public void On(string key, Action<float> action)
        {
            var e = GetEvent(key);
            if (e == null) e = new Event();
            e.OnFloat = action;
            On(key, e);
        }

        public void On(string key, Action<int> action)
        {
            var e = GetEvent(key);
            if (e == null) e = new Event();
            e.OnInt = action;
            On(key, e);
        }

        public void On(string key, Action<JSONObject> action)
        {
            var e = GetEvent(key);
            if (e == null) e = new Event();
            e.OnObj = action;
            On(key, e);
        }

        public void On(string key, Action<JSONArray> action)
        {
            var e = GetEvent(key);
            if (e == null) e = new Event();
            e.OnArr = action;
            On(key, e);
        }

        public void Off(string key)
        {
            if (eventMap.ContainsKey(key)) eventMap.Remove(key);
        }
    }
}